package sys_serv

import (
	"strconv"
	"strings"
	"ubt-rbac-service/internal/app/model"
	"ubt-rbac-service/internal/app/model/sys_mod"
	"ubt-rbac-service/internal/app/util"
	"ubt-rbac-service/internal/core/logger"
)

type sysBtn struct{}

var SysBtnServ = sysBtn{}

// Add 新增按钮
func (s *sysBtn) Add(req *sys_mod.SysBtnSaveReq) *model.Result {
	sqlStr := "INSERT INTO sys_button(btn_name, btn_code, sort, mod_id, states, add_time) VALUES ($1, $2, $3, $4, 1, EXTRACT(EPOCH FROM NOW()))"
	retCode, retMsg := util.CudData(sqlStr, req.BtnName, req.BtnCode, req.Sort, req.ModId)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// Exists 判断按钮编码是否存在
func (s *sysBtn) Exists(req *sys_mod.SysBtnExtVo) bool {
	sqlStr := "SELECT COUNT(1) AS nums FROM sys_button WHERE states=1 AND mod_id=$1 AND btn_code=$2"
	param := make([]interface{}, 0)
	param = append(param, req.ModId)
	param = append(param, req.BtnCode)
	if req.BtnId != "" {
		sqlStr += " AND btn_id!=$3"
		param = append(param, req.BtnId)
	}
	if dbMap, err := util.GetOne(sqlStr, param...); err == nil && len(dbMap) > 0 {
		if dbMap["nums"].(int64) > 0 {
			return true
		}
	}
	return false
}

// Update 修改按钮
func (s *sysBtn) Update(req *sys_mod.SysBtnSaveReq) *model.Result {
	sqlStr := "UPDATE sys_button SET btn_name=$1, btn_code=$2, sort=$3, mod_id=$4, upd_time=EXTRACT(EPOCH FROM NOW()) WHERE btn_id=$5"
	retCode, retMsg := util.CudData(sqlStr, req.BtnName, req.BtnCode, req.Sort, req.ModId, req.BtnId)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// Deletes 删除按钮
func (s *sysBtn) Deletes(req *sys_mod.SysBtnDelsReq) *model.Result {
	var (
		param []interface{}
		q     string
		n     = 0
	)
	idList := strings.Split(req.BtnIds, ",")
	for _, curId := range idList {
		n++
		q += "$" + strconv.Itoa(n) + ","
		param = append(param, curId)
	}
	q = q[:len(q)-1]
	sqlStr := "UPDATE sys_button SET states=2, upd_time=EXTRACT(EPOCH FROM NOW()) WHERE btn_id IN (" + q + ")"
	retCode, retMsg := util.CudData(sqlStr, param...)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// DelByMod 根据模块编号删除按钮
func (s *sysBtn) DelByMod(modId string) *model.Result {
	sqlStr := "UPDATE sys_button SET states=2, upd_time=EXTRACT(EPOCH FROM NOW()) WHERE mod_id=$1"
	retCode, retMsg := util.CudData(sqlStr, modId)
	return &model.Result{RetCode: retCode, RetMsg: retMsg}
}

// One 获取按钮详情
func (s *sysBtn) One(btnId string) *model.Result {
	sqlStr := "SELECT a.btn_id, a.btn_name, a.btn_code, a.sort, a.mod_id, b.mod_name, b.mod_code, a.states, a.add_time, b.upd_time " +
		"FROM sys_button a " +
		"LEFT JOIN sys_module b ON a.mod_id=b.mod_id " +
		"WHERE a.btn_id=$1"
	if dbMap, err := util.GetOne(sqlStr, btnId); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}

// Count 获取按钮数量
func (s *sysBtn) Count(req *sys_mod.SysBtnPageReq) *model.Result {
	sqlStr := "SELECT COUNT(1) AS nums FROM sys_button WHERE states=1"
	param := make([]interface{}, 0)
	var n = 0
	if req.SchName != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.SchName, " ")
		for _, name := range nameArr {
			sqlStr += "btn_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"btn_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			n += 2
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.ModId != "" {
		sqlStr += " AND mod_id=$" + strconv.Itoa(n+1)
		param = append(param, req.ModId)
	}
	if dbMap, err := util.GetOne(sqlStr, param...); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap["nums"]}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}

// Page 获取按钮分页列表
func (s *sysBtn) Page(req *sys_mod.SysBtnPageReq) *model.Result {
	sqlStr := "SELECT a.btn_id, a.btn_name, a.btn_code, b.mod_name, b.mod_code, a.sort " +
		"FROM sys_button a " +
		"LEFT JOIN sys_module b ON a.mod_id=b.mod_id " +
		"WHERE a.states=1"
	param := make([]interface{}, 0)
	var n = 0
	if req.SchName != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.SchName, " ")
		for _, name := range nameArr {
			sqlStr += "a.btn_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"a.btn_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			n += 2
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.ModId != "" {
		sqlStr += " AND a.mod_id=$" + strconv.Itoa(n+1)
		param = append(param, req.ModId)
		n += 1
	}
	sqlStr += " ORDER BY a.btn_code LIMIT $" + strconv.Itoa(n+1) + " OFFSET $" + strconv.Itoa(n+2)
	param = append(param, req.Limit)
	param = append(param, req.Offset)
	dbMap, err := util.GetAll(sqlStr, param...)
	if err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}

// Select 获取按钮下拉列表
func (s *sysBtn) Select() *model.Result {
	sqlStr := "SELECT btn_id, btn_name, btn_code, mod_id, false chked FROM sys_button WHERE states=1 ORDER BY btn_code"
	db := util.GetDbConn()
	if rows, err := db.Query(sqlStr); err == nil {
		bo := &sys_mod.SysBtnSelRes{}
		var bos []*sys_mod.SysBtnSelRes
		for rows.Next() {
			err = rows.Scan(&bo.BtnId, &bo.BtnName, &bo.BtnCode, &bo.ModId, &bo.Chked)
			if err == nil {
				bos = append(bos, bo)
				bo = &sys_mod.SysBtnSelRes{}
			} else {
				logger.Error("模块信息封装失败。" + err.Error())
				return &model.Result{RetCode: 1002, RetMsg: "模块信息封装失败"}
			}
		}
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: bos}
	}
	return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
}

// Sort 获取数量，用于排序
func (s *sysBtn) Sort(modId string) *model.Result {
	sqlStr := "SELECT COUNT(1)+1 AS nums FROM sys_button WHERE states=1 AND mod_id=$1"
	if dbMap, err := util.GetOne(sqlStr, modId); err == nil && len(dbMap) > 0 {
		return &model.Result{RetCode: 1001, RetMsg: "ok", RetData: dbMap["nums"]}
	} else {
		return &model.Result{RetCode: 1000, RetMsg: "暂无内容"}
	}
}
